package cn.sciento.boot.api.customize.commons.repository.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import cn.sciento.boot.api.customize.commons.repository.ApiCustomizeRepository;
import cn.sciento.boot.api.customize.commons.vo.ApiCustomizePoint;
import cn.sciento.boot.api.customize.commons.vo.ApiCustomizeRule;
import cn.sciento.core.redis.RedisHelper;
import cn.sciento.core.redis.safe.SafeRedisHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

public class DefaultApiCustomizeRepository implements ApiCustomizeRepository {
  private static final Logger LOGGER = LoggerFactory.getLogger(DefaultApiCustomizeRepository.class);
  private final RedisHelper redisHelper;
  @Value("${stong.service.platform.redis-db:1}")
  private int redisDb;

  public DefaultApiCustomizeRepository(RedisHelper redisHelper) {
    this.redisHelper = redisHelper;
  }

  public void saveRule(ApiCustomizeRule rule) {
    Assert.notNull(rule, "rule must not be null.");
    SafeRedisHelper.execute(this.redisDb, () -> {
      this.redisHelper.hshPut("hpfm:customize:rule", rule.getRuleCode(), this.redisHelper.toJson(rule));
    });
  }

  public ApiCustomizeRule getRule(String ruleCode) {
    Assert.notNull(ruleCode, "ruleId must not be null.");
    return (ApiCustomizeRule)SafeRedisHelper.execute(this.redisDb, this.redisHelper, () -> {
      String value = this.redisHelper.hshGet("hpfm:customize:rule", ruleCode);
      if (StringUtils.isBlank(value)) {
        LOGGER.warn("not found rule from cache for code {}", ruleCode);
        return null;
      } else {
        return (ApiCustomizeRule)this.redisHelper.fromJson(value, ApiCustomizeRule.class);
      }
    });
  }

  public List<ApiCustomizeRule> getRule(List<String> ruleCodes) {
    List<ApiCustomizeRule> rules = new ArrayList(ruleCodes.size());
    Iterator var4 = ruleCodes.iterator();

    while(true) {
      ApiCustomizeRule rule;
      do {
        do {
          if (!var4.hasNext()) {
            return rules;
          }

          String ruleCode = (String)var4.next();
          rule = this.getRule(ruleCode);
        } while(rule == null);
      } while(rule.getEnabledFlag() != null && !rule.getEnabledFlag().equals(1));

      rules.add(rule);
    }
  }

  public void deleteRule(String ruleCode) {
    Assert.notNull(ruleCode, "ruleCode must not be null.");
    SafeRedisHelper.execute(this.redisDb, () -> {
      this.redisHelper.hshDelete("hpfm:customize:rule", new Object[]{ruleCode});
    });
  }

  public void savePointRule(List<ApiCustomizePoint> points, List<String> ruleCodes) {
    Iterator var3 = points.iterator();

    while(var3.hasNext()) {
      ApiCustomizePoint point = (ApiCustomizePoint)var3.next();
      String key = ApiCustomizePoint.generateKey(point.getServiceName());
      String hashKey = point.generateHashKey();
      SafeRedisHelper.execute(this.redisDb, () -> {
        this.redisHelper.hshPut(key, hashKey, StringUtils.join(ruleCodes, ","));
      });
    }

  }

  public void deletePointRule(List<ApiCustomizePoint> points) {
    Iterator var2 = points.iterator();

    while(var2.hasNext()) {
      ApiCustomizePoint point = (ApiCustomizePoint)var2.next();
      String key = ApiCustomizePoint.generateKey(point.getServiceName());
      String hashKey = point.generateHashKey();
      SafeRedisHelper.execute(this.redisDb, () -> {
        this.redisHelper.hshDelete(key, new Object[]{hashKey});
      });
    }

  }

  public List<ApiCustomizePoint> getServicePoints(String serviceName) {
    return SafeRedisHelper.execute(this.redisDb, this.redisHelper, () -> {
      List<ApiCustomizePoint> points = new ArrayList(8);
      Map<String, String> map = this.redisHelper.hshGetAll(ApiCustomizePoint.generateKey(serviceName));
      map.forEach((key, value) -> {
        points.add(ApiCustomizePoint.generate(serviceName, key, value));
      });
      return points;
    });
  }

  public List<ApiCustomizePoint> getServicePoints(String serviceName, List<String> ruleCodes) {
    List<ApiCustomizePoint> points = this.getServicePoints(serviceName);
    return CollectionUtils.isEmpty(ruleCodes) ? points : points.stream().filter((point) -> {
      return point.getRuleCodes().containsAll(ruleCodes);
    }).map((point) -> {
      return point.setRuleCodes(ruleCodes);
    }).collect(Collectors.toList());
  }
}
